class RainDrop {
  constructor({x, y, len, v, a, angle, alpha}) {
    this.x = x;
    this.y = y;
    this.len = len;
    this.v = v;
    this.a = a;
    this.angle = angle + TAU / 4;
    this.alpha = alpha;
  }

  move() {
    this.x += this.v * cos(this.angle);
    this.y += this.v * sin(this.angle);
    this.v += this.a;
  }

  draw() {
    const endX = this.x + this.len * cos(this.angle);
    const endY = this.y + this.len * sin(this.angle);

    const col = color('#ffffff')
    col.setAlpha(this.alpha)
    stroke(col)
    noFill()
    
    line(this.x, this.y, endX, endY);
  }

  reset() {
    this.y = -this.len;
  }
}


class RainFlower {
  constructor({x, y, startWidth, startHeight, widthGrowV, heightGrowV, alpha, fadeV}) {
    this.x = x;
    this.y = y;
    this.alpha = alpha;
    this.fadeV = fadeV;

    this.width = startWidth;
    this.height = startHeight;
    this.widthGrowV = widthGrowV;
    this.heightGrowV = heightGrowV;
  }

  draw() {
    const col = color('#ffffff')
    col.setAlpha(this.alpha)
    stroke(col)
    noFill()

    ellipse(this.x, this.y, this.width, this.height);
  }

  fade() {
    this.alpha -= this.fadeV;
    this.width += this.widthGrowV;
    this.height += this.heightGrowV;
  }

  isFaded() {
    return this.alpha <= 0;
  }
}


const rainDropNum = window.innerWidth > 1000 ? 600 : 300;
const rainDrops = [];
const rainFlowers = [];
const subtitle = document.getElementsByClassName('subtitle')[0];


function makeCanvasVisible() {
  const canvas = document.getElementsByTagName('canvas')[0];
  canvas.style.position = 'absolute';
  canvas.style.zIndex = 1;
}


function setup() {
  createCanvas(windowWidth, windowHeight);
  makeCanvasVisible();

  for(let i = 0; i < rainDropNum; i++) {
    rainDrops.push(new RainDrop({
      x: random(0, width),
      y: random(-height, 0),
      len: random(4, 12),
      v: random(10, 20),
      a: 0,
      angle: 0,
      alpha: random(10, 200)
    }));
  }
}

function draw() {
  clear();

  rainDrops.forEach(rain => {
    rain.draw();
    rain.move();

    if(rain.y > random(windowHeight * 0.5, windowHeight * 1.3)) {
      const ratio = 0.33;

      rainFlowers.push(new RainFlower({
        x: rain.x + cos(rain.angle) * rain.len,
        y: rain.y + sin(rain.angle) * rain.len,
        startWidth: map(rain.len, 4, 12, 4, 12),
        startHeight: map(rain.len, 4, 12, 4 * ratio, 12 * ratio),
        widthGrowV: map(rain.len, 4, 12, 0.3, 0.9),
        heightGrowV: map(rain.len, 4, 12, 0.3 * ratio, 0.9 * ratio),
        alpha: rain.alpha * map(rain.y, windowHeight * 0.5, windowHeight * 1.3, 0.3, 1),
        fadeV: 2
      }));

      rain.reset();
    }
  });

  rainFlowers.forEach((rainFlower, i) => {
    rainFlower.draw();
    rainFlower.fade();

    if (rainFlower.isFaded()) {
      rainFlowers.splice(i, 1);
    }
  });
}